from django.shortcuts import render
from rest_framework import generics, status, permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
from django.db.models import Q, Avg, Count
from django.db.models.functions import TruncMonth
from .models import Movie, Rating, Genre, Comment
from .serializers import (
    UserSerializer, MovieSerializer, RatingSerializer, 
    GenreSerializer, MovieRecommendationSerializer, CommentSerializer
)
from .recommendation_service import MovieRecommendationService


@api_view(['POST'])
@permission_classes([permissions.AllowAny])
def register(request):
    """用户注册"""
    serializer = UserSerializer(data=request.data)
    if serializer.is_valid():
        user = serializer.save()
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'user': UserSerializer(user).data,
            'token': token.key
        }, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['POST'])
@permission_classes([permissions.AllowAny])
def login(request):
    """用户登录"""
    username = request.data.get('username')
    password = request.data.get('password')
    
    if username and password:
        user = authenticate(username=username, password=password)
        if user:
            token, created = Token.objects.get_or_create(user=user)
            return Response({
                'user': UserSerializer(user).data,
                'token': token.key
            })
        else:
            return Response(
                {'error': '用户名或密码错误'},
                status=status.HTTP_401_UNAUTHORIZED
            )
    else:
        return Response(
            {'error': '请提供用户名和密码'},
            status=status.HTTP_400_BAD_REQUEST
        )


@api_view(['POST'])
def logout(request):
    """用户登出"""
    try:
        request.user.auth_token.delete()
        return Response({'message': '成功登出'})
    except:
        return Response({'error': '登出失败'}, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_current_user(request):
    """获取当前用户信息"""
    serializer = UserSerializer(request.user)
    return Response(serializer.data)


from rest_framework.pagination import PageNumberPagination

class CustomPageNumberPagination(PageNumberPagination):
    """自定义分页类，支持动态页面大小"""
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100
    
    def get_page_size(self, request):
        """获取页面大小，限制为5、10、20"""
        page_size = request.query_params.get(self.page_size_query_param)
        if page_size:
            try:
                page_size = int(page_size)
                if page_size in [5, 10, 20]:
                    return page_size
            except ValueError:
                pass
        return self.page_size

class MovieListView(generics.ListAPIView):
    """电影列表"""
    serializer_class = MovieSerializer
    permission_classes = [permissions.IsAuthenticated]
    pagination_class = CustomPageNumberPagination
    
    def get_queryset(self):
        queryset = Movie.objects.all()
        search = self.request.query_params.get('search', None)
        genre = self.request.query_params.get('genre', None)
        
        if search:
            queryset = queryset.filter(
                Q(title__icontains=search) | Q(movie_id__icontains=search)
            )
        
        if genre:
            queryset = queryset.filter(genres__name__icontains=genre)
        
        return queryset.distinct().order_by('title')


class MovieDetailView(generics.RetrieveAPIView):
    """电影详情"""
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer
    permission_classes = [permissions.IsAuthenticated]


class GenreListView(generics.ListAPIView):
    """电影类型列表"""
    queryset = Genre.objects.all().order_by('name')
    serializer_class = GenreSerializer
    permission_classes = [permissions.AllowAny]


class RatingListCreateView(generics.ListCreateAPIView):
    """评分列表和创建"""
    serializer_class = RatingSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        return Rating.objects.filter(user=self.request.user).order_by('-timestamp')
    
    def perform_create(self, serializer):
        serializer.save(user=self.request.user)


class RatingDetailView(generics.RetrieveUpdateDestroyAPIView):
    """评分详情、更新和删除"""
    serializer_class = RatingSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        return Rating.objects.filter(user=self.request.user)


@api_view(['GET'])
def get_recommendations(request):
    """获取电影推荐"""
    algorithm = request.query_params.get('algorithm', 'hybrid')
    num_recommendations = int(request.query_params.get('num', 10))
    
    # 分页参数
    page = int(request.query_params.get('page', 1))
    page_size = int(request.query_params.get('page_size', 20))
    
    # 限制page_size的值
    if page_size not in [5, 10, 20]:
        page_size = 20
    
    service = MovieRecommendationService()
    
    # 获取更多推荐以支持分页
    total_recommendations_needed = page * page_size
    
    if algorithm == 'user_based':
        all_recommendations = service.get_user_based_recommendations(
            request.user.id, total_recommendations_needed
        )
    elif algorithm == 'item_based':
        all_recommendations = service.get_item_based_recommendations(
            request.user.id, total_recommendations_needed
        )
    elif algorithm == 'content_based':
        all_recommendations = service.get_content_based_recommendations(
            request.user.id, total_recommendations_needed
        )
    else:  # hybrid
        all_recommendations = service.get_hybrid_recommendations(
            request.user.id, total_recommendations_needed
        )
    
    # 计算分页
    total_count = len(all_recommendations)
    start_index = (page - 1) * page_size
    end_index = start_index + page_size
    
    # 获取当前页的推荐
    page_recommendations = all_recommendations[start_index:end_index]
    
    # 构建分页响应
    has_next = end_index < total_count
    has_previous = page > 1
    
    next_url = None
    previous_url = None
    
    if has_next:
        next_url = f"{request.build_absolute_uri()}?algorithm={algorithm}&num={num_recommendations}&page={page + 1}&page_size={page_size}"
    
    if has_previous:
        previous_url = f"{request.build_absolute_uri()}?algorithm={algorithm}&num={num_recommendations}&page={page - 1}&page_size={page_size}"
    
    serializer = MovieRecommendationSerializer(page_recommendations, many=True)
    
    return Response({
        'count': total_count,
        'next': next_url,
        'previous': previous_url,
        'results': serializer.data
    })


@api_view(['GET'])
def get_popular_movies(request):
    """获取热门电影"""
    num_movies = int(request.query_params.get('num', 10))
    
    popular_movies = Movie.objects.annotate(
        avg_rating=Avg('rating__rating'),
        rating_count=Count('rating')
    ).filter(
        avg_rating__isnull=False,
        rating_count__gte=5  # 至少5个评分
    ).order_by('-avg_rating', '-rating_count')[:num_movies]
    
    serializer = MovieSerializer(popular_movies, many=True)
    return Response(serializer.data)


@api_view(['GET'])
def get_user_stats(request):
    """获取用户统计信息"""
    user_ratings = Rating.objects.filter(user=request.user)
    
    stats = {
        'total_ratings': user_ratings.count(),
        'average_rating': user_ratings.aggregate(Avg('rating'))['rating__avg'] or 0,
        'favorite_genres': []
    }
    
    # 获取用户最喜欢的类型
    if user_ratings.exists():
        genre_ratings = {}
        for rating in user_ratings.filter(rating__gte=4.0):
            for genre in rating.movie.genres.all():
                if genre.name not in genre_ratings:
                    genre_ratings[genre.name] = 0
                genre_ratings[genre.name] += 1
        
        # 按评分数量排序
        sorted_genres = sorted(
            genre_ratings.items(), 
            key=lambda x: x[1], 
            reverse=True
        )[:5]
        
        stats['favorite_genres'] = [{
            'name': genre,
            'count': count
        } for genre, count in sorted_genres]
    
    return Response(stats)


@api_view(['GET', 'POST'])
@permission_classes([permissions.IsAuthenticated])
def movie_comments(request, movie_id):
    """获取或创建电影留言"""
    try:
        movie = Movie.objects.get(id=movie_id)
    except Movie.DoesNotExist:
        return Response(
            {'error': '电影不存在'}, 
            status=status.HTTP_404_NOT_FOUND
        )
    
    if request.method == 'GET':
        # 获取电影的所有留言，按时间倒序
        comments = Comment.objects.filter(movie=movie).order_by('-timestamp')
        
        # 分页处理
        page = int(request.query_params.get('page', 1))
        page_size = int(request.query_params.get('page_size', 10))
        start = (page - 1) * page_size
        end = start + page_size
        
        total_count = comments.count()
        page_comments = comments[start:end]
        
        serializer = CommentSerializer(page_comments, many=True)
        
        return Response({
            'count': total_count,
            'page': page,
            'page_size': page_size,
            'total_pages': (total_count + page_size - 1) // page_size,
            'results': serializer.data
        })
    
    elif request.method == 'POST':
        # 创建新留言
        serializer = CommentSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user, movie=movie)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
@permission_classes([permissions.IsAuthenticated])
def comment_detail(request, comment_id):
    """获取、更新或删除留言"""
    try:
        comment = Comment.objects.get(id=comment_id)
    except Comment.DoesNotExist:
        return Response(
            {'error': '留言不存在'}, 
            status=status.HTTP_404_NOT_FOUND
        )
    
    # 只有留言作者可以修改或删除
    if request.method in ['PUT', 'DELETE'] and comment.user != request.user:
        return Response(
            {'error': '您只能修改或删除自己的留言'}, 
            status=status.HTTP_403_FORBIDDEN
        )
    
    if request.method == 'GET':
        serializer = CommentSerializer(comment)
        return Response(serializer.data)
    
    elif request.method == 'PUT':
        serializer = CommentSerializer(comment, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    elif request.method == 'DELETE':
        comment.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


@api_view(['GET'])
@permission_classes([permissions.IsAdminUser])
def admin_statistics(request):
    """管理员统计数据"""
    # 评分分布统计
    rating_distribution = Rating.objects.values('rating').annotate(
        count=Count('id')
    ).order_by('rating')
    
    # 留言统计（按月）
    comment_stats = Comment.objects.extra(
        select={'month': "strftime('%%Y-%%m', timestamp)"}
    ).values('month').annotate(
        count=Count('id')
    ).order_by('month')
    
    # 电影类型统计
    genre_stats = Genre.objects.annotate(
        movie_count=Count('movie'),
        rating_count=Count('movie__rating')
    ).order_by('-movie_count')
    
    # 用户活跃度统计
    user_stats = User.objects.annotate(
        rating_count=Count('rating'),
        comment_count=Count('comment')
    ).filter(Q(rating_count__gt=0) | Q(comment_count__gt=0))
    
    # 总体统计
    total_stats = {
        'total_users': User.objects.count(),
        'total_movies': Movie.objects.count(),
        'total_ratings': Rating.objects.count(),
        'total_comments': Comment.objects.count(),
        'avg_rating': Rating.objects.aggregate(avg=Avg('rating'))['avg'] or 0,
        'active_users': user_stats.count()
    }
    
    return Response({
        'rating_distribution': list(rating_distribution),
        'comment_stats': list(comment_stats),
        'genre_stats': [{
            'name': genre.name,
            'movie_count': genre.movie_count,
            'rating_count': genre.rating_count
        } for genre in genre_stats],
        'user_activity': [{
            'username': user.username,
            'rating_count': user.rating_count,
            'comment_count': user.comment_count
        } for user in user_stats[:10]],  # 前10名活跃用户
        'total_stats': total_stats
    })


@api_view(['GET', 'POST'])
@permission_classes([permissions.IsAdminUser])
def admin_users(request):
    """管理员用户管理 - 获取用户列表和创建用户"""
    if request.method == 'GET':
        users = User.objects.annotate(
            rating_count=Count('rating'),
            comment_count=Count('comment')
        ).order_by('-date_joined')
        
        # 搜索过滤
        search = request.GET.get('search', '')
        if search:
            users = users.filter(
                Q(username__icontains=search) |
                Q(email__icontains=search) |
                Q(first_name__icontains=search) |
                Q(last_name__icontains=search)
            )
        
        paginator = PageNumberPagination()
        paginator.page_size = 20
        result_page = paginator.paginate_queryset(users, request)
        
        user_data = [{
            'id': user.id,
            'username': user.username,
            'email': user.email,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'is_staff': user.is_staff,
            'is_active': user.is_active,
            'date_joined': user.date_joined,
            'rating_count': user.rating_count,
            'comment_count': user.comment_count
        } for user in result_page]
        
        return paginator.get_paginated_response(user_data)
    
    elif request.method == 'POST':
        # 创建新用户
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            return Response({
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'is_staff': user.is_staff,
                'is_active': user.is_active,
                'date_joined': user.date_joined
            }, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
@permission_classes([permissions.IsAdminUser])
def admin_comments(request):
    """管理员留言管理"""
    comments = Comment.objects.select_related('user', 'movie').order_by('-timestamp')
    
    # 搜索过滤
    search = request.GET.get('search', '')
    if search:
        comments = comments.filter(
            Q(content__icontains=search) |
            Q(user__username__icontains=search) |
            Q(movie__title__icontains=search)
        )
    
    paginator = PageNumberPagination()
    paginator.page_size = 20
    result_page = paginator.paginate_queryset(comments, request)
    
    serializer = CommentSerializer(result_page, many=True)
    return paginator.get_paginated_response(serializer.data)


@api_view(['DELETE'])
@permission_classes([permissions.IsAdminUser])
def admin_delete_comment(request, comment_id):
    """管理员删除留言"""
    try:
        comment = Comment.objects.get(id=comment_id)
        comment.delete()
        return Response({'message': '留言删除成功'}, status=status.HTTP_200_OK)
    except Comment.DoesNotExist:
        return Response({'error': '留言不存在'}, status=status.HTTP_404_NOT_FOUND)


@api_view(['GET', 'PUT', 'DELETE'])
@permission_classes([permissions.IsAdminUser])
def admin_user_detail(request, user_id):
    """管理员用户详情管理 - 获取、更新、删除用户"""
    try:
        user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        return Response({'error': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
    
    if request.method == 'GET':
        user_data = {
            'id': user.id,
            'username': user.username,
            'email': user.email,
            'first_name': user.first_name,
            'last_name': user.last_name,
            'is_staff': user.is_staff,
            'is_active': user.is_active,
            'date_joined': user.date_joined,
            'rating_count': user.rating_set.count(),
            'comment_count': user.comment_set.count()
        }
        return Response(user_data)
    
    elif request.method == 'PUT':
        # 更新用户信息
        serializer = UserSerializer(user, data=request.data, partial=True)
        if serializer.is_valid():
            updated_user = serializer.save()
            return Response({
                'id': updated_user.id,
                'username': updated_user.username,
                'email': updated_user.email,
                'first_name': updated_user.first_name,
                'last_name': updated_user.last_name,
                'is_staff': updated_user.is_staff,
                'is_active': updated_user.is_active,
                'date_joined': updated_user.date_joined
            })
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    elif request.method == 'DELETE':
        # 删除用户
        if user.is_superuser:
            return Response({'error': '不能删除超级管理员'}, status=status.HTTP_403_FORBIDDEN)
        user.delete()
        return Response({'message': '用户删除成功'}, status=status.HTTP_200_OK)


@api_view(['GET', 'POST'])
@permission_classes([permissions.IsAdminUser])
def admin_movies(request):
    """管理员电影管理 - 获取电影列表和创建电影"""
    if request.method == 'GET':
        movies = Movie.objects.all().order_by('-id')
        
        # 搜索过滤
        search = request.GET.get('search', '')
        if search:
            movies = movies.filter(
                Q(title__icontains=search) |
                Q(movie_id__icontains=search)
            )
        
        paginator = PageNumberPagination()
        paginator.page_size = 20
        result_page = paginator.paginate_queryset(movies, request)
        
        serializer = MovieSerializer(result_page, many=True)
        return paginator.get_paginated_response(serializer.data)
    
    elif request.method == 'POST':
        # 创建新电影
        data = request.data.copy()
        # 处理genre_ids字段
        if 'genre_ids' in data and isinstance(data['genre_ids'], str):
            import json
            try:
                data['genre_ids'] = json.loads(data['genre_ids'])
            except json.JSONDecodeError:
                return Response({'error': '无效的类型数据格式'}, status=status.HTTP_400_BAD_REQUEST)
        
        serializer = MovieSerializer(data=data, context={'request': request})
        if serializer.is_valid():
            movie = serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'DELETE'])
@permission_classes([permissions.IsAdminUser])
def admin_movie_detail(request, movie_id):
    """管理员电影详情管理 - 获取、更新、删除电影"""
    try:
        movie = Movie.objects.get(id=movie_id)
    except Movie.DoesNotExist:
        return Response({'error': '电影不存在'}, status=status.HTTP_404_NOT_FOUND)
    
    if request.method == 'GET':
        serializer = MovieSerializer(movie)
        return Response(serializer.data)
    
    elif request.method == 'PUT':
        # 更新电影信息
        from django.http import QueryDict
        
        # 处理 QueryDict 和普通字典
        if isinstance(request.data, QueryDict):
            data = {}
            for key, value in request.data.items():
                data[key] = value
        else:
            data = request.data.copy()
            
        print(f"Received data: {data}")  # 调试信息
        print(f"Request content type: {request.content_type}")  # 调试信息
        print(f"genre_ids type: {type(data.get('genre_ids'))}")  # 调试信息
        print(f"genre_ids value: {data.get('genre_ids')}")  # 调试信息
        
        # 处理genre_ids字段
        if 'genre_ids' in data:
            genre_ids_value = data['genre_ids']
            if isinstance(genre_ids_value, str):
                import json
                try:
                    data['genre_ids'] = json.loads(genre_ids_value)
                    print(f"Parsed genre_ids: {data['genre_ids']}")  # 调试信息
                except json.JSONDecodeError as e:
                    print(f"JSON decode error: {e}")  # 调试信息
                    return Response({'error': f'无效的类型数据格式: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
            elif isinstance(genre_ids_value, list):
                # 如果已经是列表，直接使用
                print(f"genre_ids is already a list: {genre_ids_value}")  # 调试信息
                pass
            else:
                # 其他情况，尝试转换为列表
                print(f"Trying to convert genre_ids to list: {genre_ids_value}")  # 调试信息
                try:
                    data['genre_ids'] = list(genre_ids_value)
                except (TypeError, ValueError) as e:
                    print(f"Conversion error: {e}")  # 调试信息
                    return Response({'error': f'无效的类型数据格式: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
        
        print(f"Data before serializer: {data}")  # 调试信息
        serializer = MovieSerializer(movie, data=data, partial=True, context={'request': request})
        print(f"Serializer validation result: {serializer.is_valid()}")  # 调试信息
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        print(f"Serializer errors: {serializer.errors}")  # 调试信息
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    elif request.method == 'DELETE':
        # 删除电影
        movie.delete()
        return Response({'message': '电影删除成功'}, status=status.HTTP_200_OK)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def user_comments(request):
    """获取用户的所有留言"""
    comments = Comment.objects.filter(user=request.user).order_by('-timestamp')
    
    # 分页处理
    page = int(request.query_params.get('page', 1))
    page_size = int(request.query_params.get('page_size', 10))
    start = (page - 1) * page_size
    end = start + page_size
    
    total_count = comments.count()
    page_comments = comments[start:end]
    
    serializer = CommentSerializer(page_comments, many=True)
    
    return Response({
        'count': total_count,
        'page': page,
        'page_size': page_size,
        'total_pages': (total_count + page_size - 1) // page_size,
        'results': serializer.data
    })
